using System;
using System.Collections;
using ASPNET.StarterKit.IssueTracker.DataAccessLayer;
using System.Net.Mail;
using log4net;
using System.Collections.Generic;

namespace ASPNET.StarterKit.IssueTracker.BusinessLogicLayer
{



    //*********************************************************************
    //
    // IssueNotification Class
    //
    // Represents information about email notifications sent when an
    // issue is modified.
    //
    //*********************************************************************

    public class IssueNotification
    {

        /*** PRIVATE FIELDS ***/

        private int _Id;
        private int _IssueId;
        private string _NotificationUsername;
        private string _NotificationDisplayName;
        private string _NotificationEmail;
        private static ILog _logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);



        /*** CONSTRUCTOR ***/


        public IssueNotification(int issueId, string notificationUsername)
            : this(DefaultValues.GetIssueNotificationIdMinValue(), issueId, notificationUsername, String.Empty, String.Empty)
        { }



        public IssueNotification(int notificationId, int issueId, string notificationUsername, string notificationDisplayName, string notificationEmail)
        {
            if (issueId <= DefaultValues.GetIssueIdMinValue())
                throw (new ArgumentOutOfRangeException("IssueId"));

            _Id = notificationId;
            _IssueId = issueId;
            _NotificationUsername = notificationUsername;
            _NotificationDisplayName = notificationDisplayName;
            _NotificationEmail = notificationEmail;
        }



        /** PROPERTIES **/

        public int Id
        {
            get { return _Id; }
        }

        public int IssueId
        {
            get { return _IssueId; }
            set
            {
                if (value <= DefaultValues.GetIssueIdMinValue())
                    throw (new ArgumentOutOfRangeException("value"));
                _IssueId = value;
            }
        }



        public string NotificationUsername
        {
            get
            {
                if (_NotificationUsername == null || _NotificationUsername.Length == 0)
                    return string.Empty;
                else
                    return _NotificationUsername;
            }
        }


        public string NotificationDisplayName
        {
            get
            {
                if (_NotificationDisplayName == null || _NotificationDisplayName.Length == 0)
                    return string.Empty;
                else
                    return _NotificationDisplayName;
            }
        }


        public string NotificationEmail
        {
            get
            {
                if (_NotificationEmail == null || _NotificationEmail.Length == 0)
                    return string.Empty;
                else
                    return _NotificationEmail;
            }
        }


        /*** INSTANCE METHODS  ***/

        public bool Save()
        {
            DataAccessLayerBaseClass DBLayer = DataAccessLayerBaseClassHelper.GetDataAccessLayer();
            int TempId = DBLayer.CreateNewIssueNotification(this);
            if (TempId > 0)
            {
                _Id = TempId;
                return true;
            }
            else
                return false;
        }


        /*** STATIC METHODS  ***/

        public static bool DeleteIssueNotification(int issueId, string username)
        {
            if (issueId <= DefaultValues.GetIssueIdMinValue())
                throw (new ArgumentOutOfRangeException("issueId"));

            DataAccessLayerBaseClass DBLayer = DataAccessLayerBaseClassHelper.GetDataAccessLayer();
            return (DBLayer.DeleteIssueNotification(issueId, username));
        }

        public static void SendIssueNotifications(int issueId)
        {
            // validate input
            if (issueId <= DefaultValues.GetIssueIdMinValue())
                throw (new ArgumentOutOfRangeException("issueId"));

            DataAccessLayerBaseClass DBLayer = DataAccessLayerBaseClassHelper.GetDataAccessLayer();
            IssueNotificationCollection issNotifications = DBLayer.GetDefaultIssueNotificationsByIssueId(issueId);
            
            System.Web.Mail.SmtpMail.SmtpServer = Globals.SmtpServer;

            string notifyEmail = Globals.NotifyEmail;
            string notifyName = Globals.NotifyDisplayName;
            string desktopDefaultUrl = Globals.DesktopDefaultUrl;


            List<string> sentList = new List<string>();
            foreach (IssueNotification notify in issNotifications)
            {
                try
                {
                    if (!sentList.Contains(notify.NotificationEmail))
                    {
                        MailMessage message = new MailMessage(String.Format("\"{0}\" <{1}>", notifyName, notifyEmail),
                                                              notify.NotificationEmail,
                                                              String.Format("Issue [{0}] has been updated", issueId),
                                                              String.Format("The following issue has been updated: \n\n {0}Issues/IssueDetail.aspx?id={1}", desktopDefaultUrl, issueId));
                        SendMessage(message);
                        sentList.Add(notify.NotificationEmail);
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error(ex);
                }
            }
        }


        public static IssueNotificationCollection GetIssueNotificationsByIssueId(int issueId)
        {
            // validate input
            if (issueId <= DefaultValues.GetIssueIdMinValue())
                throw (new ArgumentOutOfRangeException("issueId"));

            DataAccessLayerBaseClass DBLayer = DataAccessLayerBaseClassHelper.GetDataAccessLayer();
            return (DBLayer.GetIssueNotificationsByIssueId(issueId));
        }

        private static void SendMessage(MailMessage message)
        {
            try
            {
                SmtpClient smtp = new SmtpClient();
                smtp.EnableSsl = false;
                smtp.Timeout = 30000;                
                DateTime dt = DateTime.Now;
                smtp.Send(message);
                //smtp.Send(message);
                TimeSpan timeToSent = DateTime.Now.Subtract(dt);
            }
            catch (Exception ex)
            {
                _logger.Error(ex);
            }
        }
    }
}
